#include <slothttpd/aio/aio_operation.hpp>
#include <slothttpd/file.hpp>

#include <cstdlib>
#include <cstring>
#include <cerrno>

#include <iostream>

#include <unistd.h>

#include <boost/asio.hpp>

class aio_service
{
public:
    aio_service() :
        aioctx(ios_)
    {
    }
    
    void run()
    {
        ios_.run();
    }
    
private:
    boost::asio::io_service ios_;
    
public:
    slothttpd::aio::linux_aio_context aioctx;
};


static void *buffer = nullptr;
const std::size_t buffer_size = 96 * 1024;

void handler(std::size_t bytes, const boost::system::error_code& err)
{
    std::cerr << "handler: " << bytes << " --> " << err << "(" << err.message() << ")" << std::endl;
    
    //::write(1, buffer, bytes);
}


int main()
{
    using namespace slothttpd::aio;
    using namespace slothttpd;
    
    aio_service aios;
    file_ptr f1, f2;
    file::open_result r1, r2;
    if (::posix_memalign(&buffer, 512, buffer_size) == 0 &&
        (r1 = file::get("slothttpd", f1, file::direct_io)) == file::success &&
        (r2 = file::get("CMakeCache.txt", f2, file::direct_io)) == file::success) {
        async_read aread, aread2, aread3;
        
        base_async_operation::operation_handler h(&handler);
        
        aread.submit(aios.aioctx, f1, (char*)buffer, buffer_size, 0, h);
        aread2.submit(aios.aioctx, f2, (char*)buffer, buffer_size, 0, h);
        aread3.submit(aios.aioctx, f1, (char*)buffer, buffer_size, 0, h);
        std::cerr << "cancel: " << aread3.cancel() << std::endl;
        aios.run();
    } else {
        std::cerr << "error: " << strerror(errno) << std::endl;
        return 1;
    }
}
